<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * Sync Controller
 *
 * @package     VisualQ Local System
 * @author      CSU OJT Students '10 - '11 (Michael Roland B. Martin)
 * @copyright   Copyright (c) 2010 - 2011, Bitstop Network Services, Inc.
 * @version     0.1b January 14, 2011
 */

class Sync extends Controller {

    function Sync()
    {
        parent::Controller();

        // Load necessary library, helper and model files
        $this->load->library('xmlrpc');
        $this->load->model(array('account_model', 'settings_model', 'statistics_model'));
        $this->load->helper(array('url', 'date'));
    }

    /**
     * Initialize the branch and company details / settings
     *
     * Used by:
     *      js/verification.js
     */
    function initialize_settings()
    {
        $this->xmlrpc->server(XMLRPC_URL, 80);
        $this->xmlrpc->method('initializeSettings');

        // Set the request data
        $request = array(
            $this->input->post('validation_key'),
            $this->input->post('product_key')
        );
        $this->xmlrpc->request($request);

        // Send data and check response
        if(!$this->xmlrpc->send_request())
        {
            echo json_encode(array('Can not connect to server database...', 0));
        } 
        else
        {
            // Get response data
            $response = $this->xmlrpc->display_response();

            // Check if records are found on server database
            if(strcmp($response['response'], 'done') == 0)
            {
                $this->db->truncate('settings');
                if(is_array($response['settings']))
                {
                    foreach($response['settings'] as $row)
                    {
                        // Check if the row to be inserted is the logo extension
                        if(strcmp($row['name'], 'logo') == 0)
                        {
                            // Get logo extension
                            $ext = $row['value'];
                        }
                        // Check if the row to be inserted is the logo string
                        if(strcmp($row['name'], 'logo_str') == 0)
                        {
                            // Get logo string, but do not save to database
                            $str = $row['value'];
                        }
                        else
                        {
                            // Initialize setting
                            $this->db->insert('settings', $row);
                        }
                    }

                    // Build logo file using the logo string and logo extension
                    if(isset($ext) && isset($str))
                    {
                        $string = base64_decode($str);
                        $handle = @fopen('images/comp_logo.' . $ext, 'x');
                        @fwrite($handle, $string);
                        @fclose($handle);
                    }

                    // Initialize the sync flag
                    $this->db->insert('settings', array('name' => 'sync_flag', 'value' => mdate('%Y-%m-%d', strtotime('+1 day'))));

                }

                $this->check_ads();

                echo json_encode(array('Verification and Initialize Settings... OK', 1));
            }
            elseif(strcmp($response['response'], 'in_use') == 0)
            {
                echo json_encode(array('Verification and Initialize Settings... THE KEYS ARE ALREADY IN USE', 0));
            }
            else
            {
                echo json_encode(array('Verification and Initialize Settings... KEYS ARE INVALID', 0));
            }
        }
    }

    /**
     * Initialize the services
     *
     * Used by:
     *      js/verification.js
     */
    function initialize_services()
    {
        $this->xmlrpc->server(XMLRPC_URL, 80);
        $this->xmlrpc->method('initializeServices');

        // Get company ID
        $result = $this->settings_model->get_company_id();
        $row = $result->row_array();

        // Set request data
        $this->xmlrpc->request(array($row['value']));

        // Send data and check response
        if(!$this->xmlrpc->send_request()) {
            echo json_encode(array('Can not connect to server database...', 0));
        } else {
            // Get response data
            $response = $this->xmlrpc->display_response();

            // Check if records are found on server database
            if($response['response'])
            {
                $this->db->truncate('services');
                if(is_array($response['services']))
                {
                    foreach($response['services'] as $row)
                    {
                        $this->db->insert('services', $row);
                    }
                }
                echo json_encode(array('Initialize Services... OK', 1));
            }
            else
            {
                echo json_encode(array('Initialize Services... NO RECORDS FOUND', 0));
            }
        }
    }

    /**
     * Initialize the branch manager and agent accounts
     *
     * Used by:
     *      js/verification.js
     */
    function initialize_accounts()
    {
        $this->xmlrpc->server(XMLRPC_URL, 80);
        $this->xmlrpc->method('initializeAccounts');

        $result = $this->settings_model->get_branch_id();
        $row = $result->row_array();
        $this->xmlrpc->request(array($row['value']));

        if(!$this->xmlrpc->send_request()) {
            echo json_encode(array('Can not connect to server database...', 0));
        } else {
            $response = $this->xmlrpc->display_response();

            if($response['response'])
            {
                $this->db->truncate('accounts');
                if(is_array($response['accounts']))
                {
                    foreach($response['accounts'] as $row)
                    {
                        $this->db->insert('accounts', $row);
                    }
                }
                echo json_encode(array('Initialize Accounts... OK', 1));
            }
            else
            {
                echo json_encode(array('Initialize Accounts... NO RECORDS FOUND', 0));
            }
        }
    }

    /**
     * Initialize the services to be handled by the agents
     *
     * Used by:
     *      js/verification.js
     */
    function initialize_accounts_services()
    {
        $this->xmlrpc->server(XMLRPC_URL, 80);
        $this->xmlrpc->method('initializeAccountsServices');

        $result = $this->account_model->get_agents_details();

        if($result->num_rows() > 0)
        {
            foreach($result->result_array() as $row)
            {
                $agent_ids[] = $row['agent_id'];
            }
            $this->xmlrpc->request($agent_ids);

            if(!$this->xmlrpc->send_request()) {
                echo json_encode(array('Can not connect to server database...', 0));
            } else {
                $response = $this->xmlrpc->display_response();

                if($response['response'])
                {
                    $this->db->truncate('accounts_services');
                    if(is_array($response['accounts_services']))
                    {
                        foreach($response['accounts_services'] as $row)
                        {
                            $this->db->insert('accounts_services', $row);
                        }
                    }
                    echo json_encode(array('Initialize Agents Services... OK', 1));
                }
                else
                {
                    echo json_encode(array('Initialize Agents Services... NO RECORDS FOUND', 0));
                }
            }
        }
    }

    /**
     * Get all IDs and 'changed' status
     *
     * Used by:
     *      sync/update/
     */
    function check_updates()
    {
        $this->xmlrpc->server(XMLRPC_URL, 80);
        $this->xmlrpc->method('checkUpdates');

        // Get company ID
        $result = $this->settings_model->get_company_id();
        $row = $result->row_array();
        $cid = $row['value'];

        // Get branch ID
        $result = $this->settings_model->get_branch_id();
        $row = $result->row_array();
        $bid = $row['value'];

        $this->xmlrpc->request(array($cid, $bid));
        if($this->xmlrpc->send_request())
        {
            $response = $this->xmlrpc->display_response();

            if($response['response'])
            {
                $params = array(
                    array(
                        'data'  => $response['accounts'],
                        'table' => 'accounts'
                    ),
                    array(
                        'data'  => $response['services'],
                        'table' => 'services'
                    ),
                    array(
                        'data'  => $response['accounts_services'],
                        'table' => 'accounts_services'
                    )
                );

                foreach($params as $row)
                {
                    $this->sync_database($row);
                }

                if($response['client'])
                {
                    $this->sync_client($cid);
                }
                if($response['branch'])
                {
                    $this->sync_branch($bid);
                }

                return 1;
            }
            else
            {
                // The client id or branch id doesn't match any record, truncate the database
                $this->db->truncate('accounts');
                $this->db->truncate('accounts_services');
                $this->db->truncate('closing_codes_tally');
                $this->db->truncate('ci_sessions');
                $this->db->truncate('dtr');
                $this->db->truncate('logs');
                $this->db->truncate('service');
                $this->db->truncate('services_tally');
                $this->db->truncate('settings');
                $this->db->truncate('statistics');

                redirect(base_url());
            }
        }
    }

    /**
     * Overwrite the old client data
     *
     * Used by:
     *      sync/check_updates.js
     */
    function sync_client($cid)
    {
        $this->xmlrpc->server(XMLRPC_URL, 80);
        $this->xmlrpc->method('getClientUpdates');

        $this->xmlrpc->request(array($cid));
        if($this->xmlrpc->send_request())
        {
            $response = $this->xmlrpc->display_response();

            if($response['response'])
            {
                foreach($response['updates'] as $insert)
                {
                    $this->db->where('name', $insert['name']);
                    $query = $this->db->get('settings');

                    if($query->num_rows() > 0)
                    {
                        $this->db->where('name', $insert['name']);
                        $this->db->update('settings', $insert);
                    }
                    else
                    {
                        $this->db->insert('settings', $insert);
                    }
                }
            }
        }
    }

    /**
     * Overwrite the branch data
     *
     * Used by:
     *      sync/check_updates.js
     */
    function sync_branch($bid)
    {
        $this->xmlrpc->server(XMLRPC_URL, 80);
        $this->xmlrpc->method('getBranchUpdates');

        $this->xmlrpc->request(array($bid));
        if($this->xmlrpc->send_request())
        {
            $response = $this->xmlrpc->display_response();

            if($response['response'])
            {
                foreach($response['updates'] as $insert)
                {
                    $this->db->where('name', $insert['name']);
                    $query = $this->db->get('settings');

                    if($query->num_rows() > 0)
                    {
                        $this->db->where('name', $insert['name']);
                        $this->db->update('settings', $insert);
                    }
                    else
                    {
                        $this->db->insert('settings', $insert);
                    }
                }

                if(is_array($response['account']))
                {
                    $this->db->where('id', $response['account'][0]['id']);
                    $query = $this->db->get('accounts');

                    if($query->num_rows() > 0)
                    {
                        $this->db->where('id', $response['account'][0]['id']);
                        $this->db->update('accounts', $response['account'][0]);
                    }
                    else
                    {
                        $this->db->where('account_type', 'manager');
                        $query = $this->db->get('accounts');

                        $manager = $query->row_array();

                        if($manager['id'] != $response['account'][0]['id'])
                        {
                            $this->db->delete('accounts', array('id' => $manager['id']));
                        }

                        $this->db->insert('accounts', $response['account'][0]);
                    }
                }
            }
        }
    }

    /**
     * Add new records, overwrite old records and delete obsolete records
     *
     * Used by:
     *      sync/check_updates.js
     *
     * @param	array
     *      data    :   id array
     *      table   :   table name
     */
    function sync_database($params)
    {
        if(is_array($params['data']))
        {
            foreach($params['data'] as $row)
            {
                $ids[] = $row['id'];

                // Store all changed records' ids
                if(isset($row['changed']))
                {
                    if($row['changed'])
                    {
                        $get[] = $row['id'];
                    }
                }
                // Check if the record is new
                $this->db->where('id', $row['id']);
                $query = $this->db->get($params['table']);

                // Store all new records' ids
                if( ! $query->num_rows() > 0)
                {
                    // Check if the array contains a value, and check if the value to be added is already an element of the array
                    if(isset($get))
                    {
                        if( ! in_array($row['id'], $get, true))
                        {
                            $get[] = $row['id'];
                        }
                    }
                    else
                    {
                        $get[] = $row['id'];
                    }
                }
            }

            // Delete records that are not found on the server database
            $this->db->where_not_in('id', $ids);
            if(strcmp($params['table'], 'accounts') == 0)
            {
                $this->db->where('account_type', 'agent');
            }
            $query = $this->db->get($params['table']);

            if($query->num_rows() > 0)
            {
                foreach($query->result_array() as $row)
                {
                    if(strcmp($params['table'], 'accounts'))
                    {
                        $this->db->delete('accounts_services', array('account_id' => $row['id']));
                        $this->db->delete('dtr', array('account_id' => $row['id']));
                        $this->db->delete('closing_codes_tally', array('account_id' => $row['id']));
                        $this->db->delete('logs', array('account_id' => $row['id']));
                        $this->db->delete('statistics', array('account_id' => $row['id']));
                    }
                    if(strcmp($params['table'], 'services'))
                    {
                        $this->db->delete('accounts_services', array('service_id' => $row['id']));
                        $this->db->delete('closing_codes_tally', array('service_id' => $row['id']));
                        $this->db->delete('logs', array('service_id' => $row['id']));
                        $this->db->delete('services_tally', array('service_id' => $row['id']));
                    }

                    $this->db->delete($params['table'], array('id' => $row['id']));
                }
            }

            if(isset($get))
            {
                $this->xmlrpc->server(XMLRPC_URL, 80);
                $this->xmlrpc->method('getUpdates');

                $table = $params['table'];

                if(strcmp($params['table'], 'accounts') == 0)
                {
                    $table = 'agents';
                }
                if(strcmp($params['table'], 'services') == 0)
                {
                    $table = 'client_services';
                }
                if(strcmp($params['table'], 'accounts_services') == 0)
                {
                    $table = 'agents_services';
                }

                $this->xmlrpc->request(array($table, array($get, 'array')));
                if($this->xmlrpc->send_request())
                {
                    $response = $this->xmlrpc->display_response();

                    if($response['response'])
                    {
                        foreach($response['updates'] as $insert)
                        {
                            $this->db->where('id', $insert['id']);
                            $query = $this->db->get($params['table']);

                            if($query->num_rows() > 0)
                            {
                                $this->db->where('id', $insert['id']);
                                $this->db->update($params['table'], $insert);
                            }
                            else
                            {
                                $this->db->insert($params['table'], $insert);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * Sends finished logs to the server
     *
     * Used by:
     *      js/front_desk.js
     */
    function send_logs()
    {
        // Load necessary library, helper and model files
        $this->load->model('ajax_model');

        $this->xmlrpc->server(XMLRPC_URL, 80);
        $this->xmlrpc->method('receiveLogs');

        // Get unsent logs
        $result = $this->ajax_model->get_unsent_log();

        if($result->num_rows() > 0)
        {
            foreach($result->row_array() as $col)
            {
                $request[] = $col;
            }
            $this->xmlrpc->request($request);
            if($this->xmlrpc->send_request())
            {
                $this->ajax_model->set_logs_sent($request[0]);
            }
        }
    }

    /**
     * Check whether to update or not
     *
     * Used by:
     *      js/front_desk.js
     */
    function update()
    {
        // Get sync flag, it should be today or days ago
        $query = $this->db->get_where('settings', array('name' => 'sync_flag', 'value <=' => mdate('%Y-%m-%d', now())));
        if($query->num_rows > 0)
        {
            if($this->check_updates() && $this->check_ads() && $this->send_statistics())
            {
                $this->db->where('name', 'sync_flag');
                $this->db->update('settings', array('value' => mdate('%Y-%m-%d', strtotime('+1 day'))));
            }
            echo json_encode(1);
        }
        else
        {
            echo json_encode(0);
        }
    }

    /**
     * Truncate the database
     *
     * Used by:
     *      manager/deactivate/
     */
    function deactivate()
    {
        $this->xmlrpc->server(XMLRPC_URL, 80);
        $this->xmlrpc->method('deactivate');

        // Get branch ID
        $result = $this->settings_model->get_branch_id();
        $row = $result->row_array();
        $bid = $row['value'];

        $this->xmlrpc->request(array($bid));

        if($this->xmlrpc->send_request())
        {
            $this->db->truncate('accounts');
            $this->db->truncate('accounts_services');
            $this->db->truncate('closing_codes_tally');
            $this->db->truncate('ci_sessions');
            $this->db->truncate('dtr');
            $this->db->truncate('logs');
            $this->db->truncate('service');
            $this->db->truncate('services_tally');
            $this->db->truncate('settings');
            $this->db->truncate('statistics');
        }
    }

    /**
     * Prepare the statistics and send to server
     *
     * Used by:
     *      sync/update/
     */
    function send_statistics()
    {
        $this->xmlrpc->server(XMLRPC_URL, 80);
        $this->xmlrpc->method('receiveStatistics');

        $result = $this->statistics_model->get_previous_statistics();

        if($result->num_rows() > 0)
        {
            foreach($result->result_array() as $row)
            {
                $data[] = array(
                    $row,
                    'struct'
                );
            }
            $statistics = array($data, 'array');
        }

        $result = $this->statistics_model->get_previous_services_tally();

        if($result->num_rows() > 0)
        {
            $branch = $this->settings_model->get_branch_id();
            $row = $branch->row_array();
            $bi = $row['value'];
            foreach($result->result_array() as $row)
            {
                $sdata[] = array(
                    array(
                        'branch_id'         => $bi,
                        'date'              => $row['date'],
                        'client_service_id' => $row['service_id'],
                        'frequency'         => $row['frequency'],
                    ),
                    'struct'
                );
            }
            $services = array($sdata, 'array');
        }

        $result = $this->statistics_model->get_previous_closing_codes_tally();

        if($result->num_rows() > 0)
        {
            foreach($result->result_array() as $row)
            {
                $cdata[] = array(
                    array(
                        'date'              => $row['date'],
                        'account_id'        => $row['account_id'],
                        'client_service_id' => $row['service_id'],
                        'closing_code'      => $row['closing_code'],
                        'frequency'         => $row['frequency']
                    ),
                    'struct'
                );
            }
            $closing_codes = array($cdata, 'array');
        }

        $result = $this->statistics_model->get_previous_dtr();

        $dtr = NULL;
        if($result->num_rows() > 0)
        {
            foreach($result->result_array() as $row)
            {
                $ddata[] = array(
                    array(
                        'account_id'        => $row['account_id'],
                        'action'            => $row['action'],
                        'time'              => $row['time']
                    ),
                    'struct'
                );
            }
            $dtr = array($ddata, 'array');
        }
        
        $request = array(
            $statistics,
            $services,
            $closing_codes,
            $dtr
        );

        $this->xmlrpc->request($request);
        if($this->xmlrpc->send_request())
        {
            return 1;
        }
    }

    /**
     * Edit the ad player playlist
     *
     */
    function edit_playlist()
    {
        $this->load->helper('directory');

        $filenames = check_directory("movie/", "flv");
        $list = '';
        foreach ($filenames as $value)
        {
            $list .= '<playitem path="../movie/' . $value . '" options="" clickurl="" clicktarget="_blank" endurl="" styleoftarget="browser" endtarget=""/>';
        }

        $output_path = 'player/medialist.xml';

        $handle = @fopen($output_path,'w+');

        @fwrite($handle,'<?xml version="1.0" encoding="UTF-8"?><playlist>' . $list . '</playlist>');
    }

    function check_ads()
    {
        $this->load->helper('directory');

        $this->xmlrpc->server(XMLRPC_URL, 80);
        $this->xmlrpc->method('checkAds');

        $this->xmlrpc->request(array(1));

        if($this->xmlrpc->send_request())
        {
            $response = $this->xmlrpc->display_response();

            if($response['response'])
            {
                // Check local ads if obsolete
                $filenames = check_directory("movie/", "flv");
                foreach ($filenames as $value)
                {
                    if( ! array_search($value, $response['ad']))
                    {
                        unlink('movie/' . $value);
                    }
                }

                // Sync ads
                foreach($response['ad'] as $ad)
                {
                    $this->sync_ad($ad);
                }

                $this->edit_playlist();

                return 1;
            }
        }
        return 0;
    }

    function sync_ad($ad)
    {
        $this->xmlrpc->server(XMLRPC_URL, 80);
        $this->xmlrpc->method('getAd');

        $this->xmlrpc->request(array($ad));

        if($this->xmlrpc->send_request())
        {
            $response = $this->xmlrpc->display_response();
            
            $ad_path = 'movie/' . $ad;
            if(@file_exists($ad_path))
            {
                $ad_content = base64_encode(file_get_contents($ad_path));

                if(strcmp($response['ad'], $ad_content) != 0)
                {
                    $string = base64_decode($response['ad']);
                    $handle = @fopen('movie/' . $ad, 'x');
                    @fwrite($handle, $string);
                    @fclose($handle);
                }
            }
            else
            {
                $string = base64_decode($response['ad']);
                $handle = @fopen('movie/' . $ad, 'x');
                @fwrite($handle, $string);
                @fclose($handle);
            }

        }
    }

}

/* End of file sync.php */
/* Location: ./system/application/controllers/sync.php */